package org.etnaframework.module.base.logback;

import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.etnaframework.module.base.config.IgnoredPackages;
import org.etnaframework.module.base.utils.HttpClientUtils;
import org.etnaframework.module.base.utils.HttpClientUtils.HttpClientBuilder;
import org.etnaframework.module.base.utils.notify.DingTalkRobotUtils;

import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;

/**
 * 自定义logback转换器，用于输出精简的调用栈信息
 *
 * @author jayaf
 * @since 2024-09-19
 */
public class FileNameAndMethodNameConverter extends ClassicConverter {

    private static final Set<String> IGNORE_LOGBACK = new LinkedHashSet<>();

    static {
        addIgnoreForLogback(HttpClientUtils.class);
        addIgnoreForLogback(HttpClientBuilder.class);
        addIgnoreForLogback(DingTalkRobotUtils.class);
    }

    public static void addIgnoreForLogback(Class<?> clazz) {
        IGNORE_LOGBACK.add(clazz.getName());
    }

    public String convert(ILoggingEvent le) {
        StackTraceElement[] cda = le.getCallerData();
        if (cda != null) {
            for (StackTraceElement e : cda) {
                // 排除框架类的调用栈，专注于业务来源，方便排查问题
                if (IGNORE_LOGBACK.contains(e.getClassName())) {
                    continue;
                }
                String fileName = Optional.ofNullable(e.getFileName()).orElse("").replaceAll("\\.java$", "").replaceAll("\\.kt$", "");
                return String.format("%s:%d #%s", fileName, e.getLineNumber(), e.getMethodName());
            }
        }
        return CallerData.NA;
    }
}
